﻿# include "assessment.h"
#import "AppDelegate.h"
#import "UserConfig.h"

int wake_num=0;
int REM_num=0;
int NREM1_num=0;
int NREM2_num=0;
int NREM3_num=0;
int tot_num=0;
int jam_num=0;
int stages[3000];
/*
 *
 * 从文件中读取分类报告并统计各个阶段的个数 1--NREM3, 2—NREM2, 3—NREM1，4—REM,  5—Wake 并放入对应的全局变量中
 
 @return 返回一共从文件中读入的数字的总个数
 
 
 */


int reading (char *data,int data_length){
    int i=0;
    wake_num = 0;//新添加，初始化
    REM_num=0;
    NREM1_num=0;
    NREM2_num=0;
    NREM3_num=0;
    tot_num=0;
    jam_num=0;//干扰的计数
    
    for (i=0; i<data_length; i++)
    {
        stages[i] = (int)data[i];
        switch(data[i]){
            case 1:
                NREM3_num++;
                break;
            case 2:
                NREM2_num++;
                break;
            case 3:
                NREM1_num++;
                break;
            case 4:
                REM_num++;
                break;
            case 5:
                wake_num++;
                break;
            case 6:
                jam_num++;
                break;
            default:
                break;
        }
    }
    return i;
}
/*
 * 对睡眠报告进行总分析
 * @param :
 * ca 用于switch的选择语句
 ca=1：文件是夜晚的睡眠报告
 ca=2: 时间在1小时到4小时，没有评分。 现在修改成1小时-3小时没有评分。
 Ca=3:  文件是午休的睡眠报告
 
 结果打印在屏幕上
 
 */
void assessment(char *data,int data_length){
    int num;
    int start_index;
    int end_index;
    int wakeTimes;
    int mark;
    int currentStage;
    int index;
    int ca;
    double REM_duration;
    double N3_duration;
    double N2_duration;
    double N1_duration;
    double JAM_duration;
    
    int i = 0 ;
    for (i = 0 ; i <data_length; i++) {
        printf("打印打印打印%d\n",data[i]);
    }
    
    num=reading(data,data_length);
    if (num>=LENGTH_SCORE)
    {
        ca=1;
    }
    else if(num>180)
    {
        ca=2;
        //保存一下
        UserConfig * config = [UserConfig sharingUserConfig];
        AppDelegate * delegate = [[UIApplication sharedApplication]delegate];
        delegate.sleepScore = 0;//保存睡眠得分
        [config setSleepScore:@"0"];//保存睡眠得分。
        TJJLog(@"2-保存睡眠得分0");
    }
    else
    {
        ca=3;
        //保存一下
        UserConfig * config = [UserConfig sharingUserConfig];
        AppDelegate * delegate = [[UIApplication sharedApplication]delegate];
        delegate.sleepScore = 0;//保存睡眠得分
        [config setSleepScore:@"0"];//保存睡眠得分。
        TJJLog(@"2-保存睡眠得分0");
    }
    switch(ca)
    {
        case 1:
            start_index=sleepOnSet(stages,num);
            end_index=sleepOff(stages,num,start_index);
            wakeTimes=wakeTime(stages, start_index,end_index);
            mark=nightSleepRating(stages,start_index,end_index,num,wakeTimes);
            
            printf("The starting number:%d\n",start_index);
            printf("The ending number:%d\n",end_index);
            printf("wakeTimes:%d\n",wakeTimes);
            printf("The marks:%d\n",mark);
            if(mark>=80)
            {
                printf("您的睡眠质量很优秀\n");
            }
            else if(mark>=60&&mark<80)
            {
                printf("您的睡眠良好\n");
            }
            else {
                printf("您的睡眠一般\n");
            }
            
            
            index=1;
            currentStage=5;
            while(1){
                int len=0;
                index=detectNextStage(stages,num,index,currentStage);
                if (index==0)
                    break;
                currentStage=stages[index];
                disp( index, currentStage);
                if(currentStage==1){
                    len=stageLength(stages,num,index,currentStage);
                    eachStageAssess(len);
                }
            }
            
            REM_duration=REM_num*1.0/2;
            N3_duration=NREM3_num*1.0/2;
            N2_duration=NREM2_num*1.0/2;
            N1_duration=NREM1_num*1.0/2;
            JAM_duration=jam_num*1.0/2;
            
            printf("您的浅睡时间为：%f分钟！\n",N1_duration);
            printf("您的轻睡时间为：%f分钟！\n",N2_duration);
            printf("您的深睡时间为：%f分钟！\n",N3_duration);
            printf("您的快速眼动时间为：%f分钟！\n",REM_duration);
            printf("接触不良：%f分钟！\n",JAM_duration);
            break;
        case 2:
            REM_duration=REM_num*1.0/2;
            N3_duration=NREM3_num*1.0/2;
            N2_duration=NREM2_num*1.0/2;
            N1_duration=NREM1_num*1.0/2;
            JAM_duration=jam_num*1.0/2;
            printf("您的睡眠时间不够3个小时，将不进入评分系统!!\n");
            printf("您的浅睡时间为：%f分钟！\n",N1_duration);
            printf("您的轻睡时间为：%f分钟！\n",N2_duration);
            printf("您的深睡时间为：%f分钟！\n",N3_duration);
            printf("您的快速眼动时间为：%f分钟！\n",REM_duration);
            printf("接触不良：%f分钟！\n",JAM_duration);
            
            break;
        case 3:
            REM_duration=REM_num*1.0/2;
            N3_duration=NREM3_num*1.0/2;
            N2_duration=NREM2_num*1.0/2;
            N1_duration=NREM3_num*1.0/2;
            JAM_duration=jam_num*1.0/2;

            printf("您的小睡浅睡时间为：%f分钟！\n",N1_duration);
            printf("您的小睡轻睡时间为：%f分钟！\n",N2_duration);
            printf("您的小睡深睡时间为：%f分钟！\n",N3_duration);
            printf("您的小睡快速眼动时间为：%f分钟！\n",REM_duration);
            printf("接触不良：%f分钟！\n",JAM_duration);
            break;
        default:
            break;
    }
    UserConfig *config = [UserConfig sharingUserConfig];
    int intN3 = N3_duration;
    NSString *N3 = [[NSString alloc]initWithFormat:@"%d",intN3 ];
    [config setsleepShenShuiTime:N3];  //设置深睡眠时间
    
    int intREm = REM_duration;
    NSString *REM = [[NSString alloc]initWithFormat:@"%d",intREm ];
    [config setDreamTime:REM];  //设置做梦时间长度
    
    //1.保存N3_duration 是深睡 单位分钟
    //2.REM_duration表示做梦 单位分钟Float
    //3.
    
}

/*
 *
 * 对整晚的睡眠报告进行分析，并给出最后得分
 @param
 *st: 睡眠报告的指针
 Start_index: 刚开始进入入睡状态是的时间索引
 End_index: 睡眠结束时的时间索引
 N: 记录的失眠时间段的总个数
 @return:  返回mark 夜晚睡眠得分
 
 */

int nightSleepRating(int *st,int start_index,int end_index,int N, int wakeTimes){
    // sleeping rating standards as follows
    // (1). the duration of NREM3 45 marks the average time is 1.5 hs
    
    // the proportion of each stage and total time; 30 marks
    // the time spend for falling asleep (the speed) 5 marks the durations 0~5 5~15,15~30,>30 mins
    // the numbers of waking up during the entire night 5 marks 0 的 5 1 得 3， 2 得1，>=3 得 0
    // the time duration of the REM 5 marks the average time is 1 hs
    // latency to REM 1 marks >50 得 1
    // latency to NREM3 1 marks < 20 得 1
    int lat_to_NREM3=0;
    int lat_to_REM=0;
    
    int NREM3_thre1=120;//finally
    int NREM3_thre2=30;//finally
    int NREM3_thre3=300; //添加
    
    int REM_thre1=300;
    int REM_thre2=160;
    int REM_thre3=60;  // 添加
    int REM_thre4=30;  // 添加
    
    int i;
    
    int mark;
    
    for(i=start_index;i<N-2;i++){
        if(st[i]==1&&st[i+1]==1&&st[i+2]==1){
            break;
        }
        lat_to_NREM3++;
    }
    
    for(i=start_index;i<N-3;i++){
        if(st[i]==4&&st[i+1]==4&&st[i+2]==4&&st[i+3]==4){
            break;
        }
        
        lat_to_REM++;
    }
    ////////////////////////////////////////////
    //estimate the quality of the night_sleep
    ////////////////////////////////////////////
    double marks1=0;
//    if(NREM3_num>NREM3_thre1&&NREM3_num<=(NREM3_thre1+100)){
//        marks1=floor((NREM3_num-NREM3_thre1)/10)+35;
//    }
    if(NREM3_num>NREM3_thre1&&NREM3_num<=(NREM3_thre3)){//修改
//        marks1=floor((NREM3_num-NREM3_thre1)/(10.0*(NREM3_thre3-NREM3_thre1)))+30.0;
        marks1=floor((NREM3_num-NREM3_thre1)*(15.0/(NREM3_thre3-NREM3_thre1)))+20.0;//再次修改 finally
    }
    else if(NREM3_num<=NREM3_thre1&&NREM3_num>NREM3_thre2){
//        marks1=(NREM3_num-NREM3_thre2)*(15.0/(NREM3_thre1-NREM3_thre2))+15;
        marks1=(NREM3_num-NREM3_thre2)*(10.0/(NREM3_thre1-NREM3_thre2))+10;//再次修改
    }
    else if(NREM3_num<=NREM3_thre2){
//        marks1=NREM3_num*(15.0/NREM3_thre2);
        marks1=NREM3_num*(10.0/NREM3_thre2);//再次修改
    }
    else{
//        marks1=45;
//        marks1=45-5*exp(NREM3_thre3-NREM3_num);//修改
        marks1=40-5*exp((NREM3_thre3-NREM3_num)/100.0);//再次修改 finally
    }
    
    
    /////////////////////////////////////////////////////
    // the marks from the speeds of falling asleep
    //////////////////////////////////////////////////////
    double marks2;
    if(start_index<10){
        marks2=4;
    }
    else if(start_index>=10&&start_index<30){
        marks2=3;
    }
    else if(start_index>=30&&start_index>60)
    {
        marks2=2;
    }
    else
    {
        marks2=1;//finally
    }
    //////////////////////////////////////////////
    // the marks from the numbers of awake
    /////////////////////////////////////////////
    double marks3;
    if(wakeTimes<=1){
        marks3=3;//finally
    }
    else if(wakeTimes>1&&wakeTimes<=3){
        marks3=2;//finally
    }
    else if(wakeTimes==4){
        marks3=1;
    }
    else {
        marks3=0;
    }
    /////////////////////////////////////////////////
    //the marks from the REM stage
    /////////////////////////////////////////////////
    double marks4;
//    if(REM_num>REM_thre1){
    if(REM_num>REM_thre1 || REM_num < REM_thre4){//修改
        marks4=0;
    }
    else if(REM_num>REM_thre2&&REM_num<=REM_thre1){
//        marks4=3;
        marks4=2;//修改
    }
    else if (REM_num>REM_thre3)//添加
    {
        marks4 = 4;
    }
    else {
//        marks4=4;
        marks4=2;//修改
    }
    ///////////////////////////////////////////////////
    //the marks from the latency to NREM3
    ///////////////////////////////////////////////
    double marks5=0;
    if(lat_to_NREM3<20){
        marks5=3;//finally
    }
    else if(lat_to_NREM3>=20 && lat_to_NREM3<80){
        marks5=3-floor((lat_to_NREM3-20)/20.0);//finally
    }
    else{
        marks5=0;
    }
    /////////////////////////////////////////////////
    //the marks from the latency to REM
    /////////////////////////////////////////////////
    double marks6=0;
    if(lat_to_REM>140){
        marks6=2;//finally
    }
    else if(lat_to_REM<=140){
        marks6=1;//finally
    }
    //////////////////////////////////////////////////
    //sleep efficacy
    ////////////////////////////////////////////////////
    double marks7=0;
    double effi=(double)(end_index-start_index)/N;
    if(effi>0.9){
        marks7=2;
    }
    else{
        marks7=0;
    }
    double marks8;
//    if (end_index-start_index>840){
    if (NREM3_num+NREM2_num+NREM1_num+REM_num>720){//再次修改  finally
//        marks8=30;
        marks8=40;//再次修改
    }
    else{
//        marks8=30*(end_index-start_index)/840.0;
        marks8=40*(NREM3_num+NREM2_num+NREM1_num+REM_num)/720.0;//再次修改 finally
    }
    //////////////////////////
    // total mark
    ////////////////////////
    mark=(int)(marks1+marks2+marks3+marks4+marks5+marks6+marks7+marks8);
    printf("marks1:%lf\n",marks1);
    printf("marks2:%lf\n",marks2);
    printf("marks3:%lf\n",marks3);
    printf("marks4:%lf\n",marks4);
    printf("marks5:%lf\n",marks5);
    printf("marks6:%lf\n",marks6);
    printf("marks7:%lf\n",marks7);
    printf("marks8:%lf\n",marks8);
    printf("mark:%d\n",mark);
    //保存一下
    NSString *myMark = [[NSString alloc] initWithFormat:@"%d",mark];
    UserConfig *config = [UserConfig sharingUserConfig];
    AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
    delegate.sleepScore = mark;//保存睡眠得分
    [config setSleepScore:myMark];//保存睡眠得分。
    TJJLog(@"保存睡眠得分%@",myMark);
    return mark;
}
/*
 * 检测进入睡眠状态的睡眠时间索引 （index）
 @param
 *st: 从文件中读入睡眠阶段数据的指针
 N: st 中存的数的总数
 @return：返回进入入睡状态的 index的值。
 
 */
int sleepOnSet(int *st,int N){
    int i=0;
    while(i<N-5){
//        if(st[i]!=5&&st[i+1]!=5&&st[i+2]!=5&&st[i+3]!=5&&st[i+4]!=5){
        if(st[i]!=5&&st[i+1]!=5&&st[i+2]!=5&&st[i+3]!=5&&st[i+4]!=5&&st[i]!=6&&st[i+1]!=6&&st[i+2]!=6&&st[i+3]!=6&&st[i+4]!=6){//修改
            return i;
        }
        i++;
    }
    return i;
}
/*
 *
 * 检测出睡眠结束时间index
 @param
 st[]: 从文件中读入睡眠阶段数据的数组
 N: st 中存的数的总数
 
 */

int sleepOff(int *st,int N,int start_index){
    int i;
    for(i=N-1;i<start_index;i--){
//        if(st[i]!=5&& st[i-1]!=5&&st[i-2]!=5)
        if(st[i]!=5&& st[i-1]!=5&&st[i-2]!=5&&st[i]!=6&& st[i-1]!=6&&st[i-2]!=6)
        {//修改
            break;
        }
    }
    return i;
}
/*
 * 检测在睡眠期间醒来了几次
 @ param
 St: 储存睡眠阶段的数组
 Start_index: 开始睡眠时的索引
 End_index: 结束睡眠时的索引
 @return 睡觉期间醒的次数
 */
int wakeTime(int *st,int start_index,int end_index){
    int num=0;
    int i;
    for(i=start_index;i<end_index-1;i++){
        if(st[i]==5&&st[i+1]!=5){
            num++;
        }
    }
    return num;
}
/*
 *
 * 检测下一个阶段发生的时间index
 @param
 St[]: 阶段的数组
 N： 数据元素的总个数
 Start_index: 从这个位置开始分析
 currentStage: 目前的阶段状态
 
 */
int detectNextStage( int *st, int N,int start_index,int currentStage){
    int i;
    int num=0;
    int label=0;
    int index=0;
    int stageTemp=currentStage;
    if(start_index>=N-1){
        return 0;
    }
    for(i=start_index;i<N;i++){
        if(st[i]==currentStage){
            num=0;
            label=0;
        }
        if(st[i]!=stageTemp){
            stageTemp=st[i];
            label=1;
            num=0;
        }
        if(st[i]==stageTemp&&label==1){
            num++;
        }
        if(num>=10){
            index=i-9;
            break;
        }
    }
    return index;
}	
/*
 * 
 * 显示出从开始睡觉经过了多久开始进入下个阶段
 因为没时间点，所以以秒显示
 */	
void disp(int index,int currentStage){
    int seconds;
    seconds=index*30;
    switch(currentStage){
        case 1://深睡
            printf("经过了%d秒，进入深度睡眠！！\n",seconds);
            break;
        case 2://轻睡
            printf("经过了%d秒，进入轻度睡眠！！\n",seconds);
            break;
        case 3://浅睡
            printf("经过了%d秒，进入浅度睡眠！！\n",seconds);
            break;
        case 4://做梦
            printf("经过了%d秒，进入快速眼动期！！\n",seconds);
            break;
        case 5://清醒
            printf("经过了%d秒，你清醒了一次！！\n",seconds);
            break;
        case 6://接触不良
            printf("接触不良经过了%d秒！！\n",seconds);
            break;
        default:
            break;
    }
}
/*
 * 计算出从 start_index 位置开始这个阶段持续的时间,以分钟计算
 * @return len 持续的分钟数
 */	
int stageLength(int *st,int N,int start_index,int currentstage){
    int len;
    int i;
    len=0;
    for(i=start_index;i<N-1;i++){
        if(st[i]==currentstage){
            len++;
        }
        else 
        {
            break;
        }
    }		
    return len;
}
/*
 *输入每个深睡阶段的时间，然后给出评分
 传入连续的 1的个数
 
 */	
void eachStageAssess(int len){
    int min=len/2;
    printf("深睡时间%d分钟!!\n",min);
    if(min>20){
        printf("优秀!!\n");
    }
    else if(min<=20&&min>10){
        printf("良好!!\n");	
    }
    else {
        printf("加油！！\n");
    }
    
}
